package savelog;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;

import com.dropbox.client2.DropboxAPI;
import com.dropbox.client2.android.AndroidAuthSession;
import com.dropbox.client2.android.AuthActivity;
import com.dropbox.client2.session.AccessTokenPair;
import com.dropbox.client2.session.AppKeyPair;
import com.dropbox.client2.session.Session.AccessType;
import com.dropbox.client2.session.TokenPair;

/**
 * Title: MainActivity class for CSIS 343 Final Project 
 * Description: CS 343 Final Project - MainActivity This class will handle displaying the main menu 
 * and directs you to the other activities
 * 
 * @author Erik Olson
 * @email erik.olson-5@my.uwrf.edu
 * @author Mike Harmon
 * @email michael.harmon@my.uwrf.edu
 * @author Jack Friermuth
 * @email jack.friermuth@my.uwrf.edu
 * @author Luke Vang
 * @email luke.vang@my.uwrf.edu
 * @author Casey Golla
 * @email casey.golla@my.uwrf.edu
 * @date December 4th 2012
 */
public class MainActivity extends Activity {

	// /////////////////////////////////////////////////////////////////////////
	// Your app-specific settings. //
	// /////////////////////////////////////////////////////////////////////////

	// Replace this with your app key and secret assigned by Dropbox.
	// Note that this is a really insecure way to do this, and you shouldn't
	// ship code which contains your key & secret in such an obvious way.
	// Obfuscation is good.
	final static private String APP_KEY = "8v6c5u5qwmivn9u";
	final static private String APP_SECRET = "enydp4jrwtzgn55";

	// If you'd like to change the access type to the full Dropbox instead of
	// an app folder, change this value.
	final static private AccessType ACCESS_TYPE = AccessType.APP_FOLDER;

	// /////////////////////////////////////////////////////////////////////////
	// End app-specific settings. //
	// /////////////////////////////////////////////////////////////////////////

	// You don't need to change these, leave them alone.
	final static protected String ACCOUNT_PREFS_NAME = "prefs";
	final static private String ACCESS_KEY_NAME = "ACCESS_KEY";
	final static private String ACCESS_SECRET_NAME = "ACCESS_SECRET";

	public static DropboxAPI<AndroidAuthSession> mApi;

	private boolean mLoggedIn;

	private TextView mSubmit;

	private final String path = Environment.getExternalStorageDirectory().toString(); // directory to external storage

	private String mSaveFileName;
	private TableRow mGameList;
	private TableRow mSettingList;
	private TableRow mUpdate;
	private TableRow mDropBox;

	public static DataSource data;

	public static ListDeviceDir list;
	public static ArrayList<String> directories;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		
		setContentView(R.layout.main_screen);
		
		data = new DataSource(this);
		data.open();

		if (savedInstanceState != null) {
			mSaveFileName = savedInstanceState.getString("mSaveFileName");
		}

		mUpdate = (TableRow) findViewById(R.id.updateRow);
		mUpdate.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {

				Intent i = new Intent(MainActivity.this, UpdateActivity.class);
				startActivity(i);

			}

		});

		mGameList = (TableRow) findViewById(R.id.gameListRow);
		mGameList.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				Intent i = new Intent(MainActivity.this, GameListActivity.class);
				startActivity(i);
			}

		});

		mSettingList = (TableRow) findViewById(R.id.settingsRow);
		mSettingList.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				Intent i = new Intent(MainActivity.this, SettingActivity.class);
				startActivity(i);

			}

		});

		// We create a new AuthSession so that we can use the Dropbox
		// API.
		AndroidAuthSession session = buildSession();

		mApi = new DropboxAPI<AndroidAuthSession>(session);

		checkAppKeySetup();


		mSubmit = (TextView) findViewById(R.id.dropBoxText);
		mSubmit.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				// This logs you out if you're logged in, or vice versa
				if (mLoggedIn) {
					logOut();
				} else {
					// Start the remote authentication
					mApi.getSession().startAuthentication(MainActivity.this);
				}
			

			}

		});
		
		mDropBox = (TableRow) findViewById(R.id.dropBoxRow);

		// Display the proper UI state if logged in or not
		setLoggedIn(mApi.getSession().isLinked());
	}

	/**
	 * 
	 * onSaveInstanceState - saves current state of activity and can retrieve
	 * state of any interupts occur to activity
	 * 
	 */
	@Override
	protected void onSaveInstanceState(Bundle outState) {
		outState.putString("mSaveFileName", mSaveFileName);
		super.onSaveInstanceState(outState);
	}

	/**
	 * 
	 * onResume() - when MainActivity resumes we grab the dropbox session, if
	 * there are any issues the user receives a error message
	 * 
	 */
	@Override
	protected void onResume() {
		super.onResume();
		AndroidAuthSession session = mApi.getSession();

		// The next part must be inserted in the onResume() method of the
		// activity from which session.startAuthentication() was called, so
		// that Dropbox authentication completes properly.
		if (session.authenticationSuccessful()) {
			try {
				// Mandatory call to complete the auth
				session.finishAuthentication();

				// Store it locally in our app for later use
				TokenPair tokens = session.getAccessTokenPair();
				storeKeys(tokens.key, tokens.secret);
				setLoggedIn(true);
			} catch (IllegalStateException e) {
				showToast("Couldn't authenticate with Dropbox:"
						+ e.getLocalizedMessage());
			}
		}

	}

	/**
	 * 
	 * logOut() - unlinks dropbox session, clears users keys, and sets isLogged
	 * to false
	 * 
	 */

	private void logOut() {
		// Remove credentials from the session
		mApi.getSession().unlink();

		// Clear our stored keys
		clearKeys();
		// Change UI state to display logged out version
		setLoggedIn(false);
	}

	/**
	 * Convenience function to change UI state based on being logged in Also
	 * calls createDBDir method, this method call had to be here for method to
	 * work correctly.
	 */
	private void setLoggedIn(boolean loggedIn) {
		mLoggedIn = loggedIn;
		if (loggedIn) {
			mSubmit.setText("Unlink from Dropbox");
			mDropBox.setVisibility(View.VISIBLE);
			SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME,
					Context.MODE_PRIVATE);
			String device_name = prefs.getString("deviceName", "");
			createDBDir(device_name, mLoggedIn);

			list = new ListDeviceDir(this, mApi, device_name);
			list.execute();

		} else {
			mSubmit.setText("Link with Dropbox");
		}
	}

	/**
	 * 
	 * checkAppyKeySetup() checks to see if manifest is setup correctly, abd if
	 * APP_KEY and APP_SECRET has been correctly genereated
	 * 
	 */
	private void checkAppKeySetup() {
		// Check to make sure that we have a valid app key
		if (APP_KEY.startsWith("CHANGE") || APP_SECRET.startsWith("CHANGE")) {
			showToast("You must apply for an app key and secret from developers.dropbox.com, and add them to the SaveLog ap before trying it.");
			finish();
			return;
		}

		// Check if the app has set up its manifest properly.
		Intent testIntent = new Intent(Intent.ACTION_VIEW);
		String scheme = "db-" + APP_KEY;
		String uri = scheme + "://" + AuthActivity.AUTH_VERSION + "/test";
		testIntent.setData(Uri.parse(uri));
		PackageManager pm = getPackageManager();
		if (0 == pm.queryIntentActivities(testIntent, 0).size()) {
			showToast("URL scheme in your app's "
					+ "manifest is not set up correctly. You should have a "
					+ "com.dropbox.client2.android.AuthActivity with the "
					+ "scheme: " + scheme);
			finish();
		}
	}

	/**
	 * This method creates a toast to be displayed to android device
	 * 
	 * @param msg
	 *            , not null
	 */

	private void showToast(String msg) {
		Toast error = Toast.makeText(this, msg, Toast.LENGTH_LONG);
		error.show();
	}

	/**
	 * Shows keeping the access keys returned from Trusted Authenticator in a
	 * local store, rather than storing user name & password, and
	 * re-authenticating each time (which is not to be done, ever).
	 * 
	 * @return Array of [access_key, access_secret], or null if none stored
	 */
	private String[] getKeys() {
		SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
		String key = prefs.getString(ACCESS_KEY_NAME, null);
		String secret = prefs.getString(ACCESS_SECRET_NAME, null);
		if (key != null && secret != null) {
			String[] ret = new String[2];
			ret[0] = key;
			ret[1] = secret;
			return ret;
		} else {
			return null;
		}
	}

	/**
	 * Shows keeping the access keys returned from Trusted Authenticator in a
	 * local store, rather than storing user name & password, and
	 * re-authenticating each time (which is not to be done, ever).
	 */
	private void storeKeys(String key, String secret) {
		// Save the access key for later
		SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
		Editor edit = prefs.edit();
		edit.putString(ACCESS_KEY_NAME, key);
		edit.putString(ACCESS_SECRET_NAME, secret);
		edit.commit();
	}

	/**
	 * 
	 * clearKeys() removes all account keys
	 * 
	 */
	private void clearKeys() {
		SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
		Editor edit = prefs.edit();
		edit.clear();
		edit.commit();
	}

	/**
	 * This method builds the authorization session with dropbox
	 * 
	 * @return session
	 * 
	 */
	private AndroidAuthSession buildSession() {
		AppKeyPair appKeyPair = new AppKeyPair(APP_KEY, APP_SECRET);
		AndroidAuthSession session;

		String[] stored = getKeys();
		if (stored != null) {
			AccessTokenPair accessToken = new AccessTokenPair(stored[0],
					stored[1]);
			session = new AndroidAuthSession(appKeyPair, ACCESS_TYPE,
					accessToken);
		} else {
			session = new AndroidAuthSession(appKeyPair, ACCESS_TYPE);
		}

		return session;
	}

	/**
	 * The createDir() method creates a backup directory in the users android
	 * devices root directory. The directory ROM/backup will be created on first
	 * start of the MainActivity.
	 * 
	 * @param dirPath
	 *            the dirPath, not null
	 * @return true if the file is created, false if the file exists or has not
	 *         been created
	 */
	public boolean createDir(String dirPath) {
		File dirNew = new File(path, dirPath);
		if (!dirNew.exists()) {
			return dirNew.mkdirs();
		}
		return false;
	}

	/**
	 * Creates a new folder in the users dropbox account. The path given in the
	 * parameters is the folder name that will be created in the apps root. This
	 * method executes in the background running on aysnc to help regulate
	 * proper usage of UI Thread.
	 * 
	 * @param path
	 *            the path parameter, not null
	 */
	public void createDBDir(String path, boolean loggedIn) {
		if (loggedIn) {

			CreateDBFolder newFolder = new CreateDBFolder(MainActivity.this,
					mApi, path);
			newFolder.execute();
		}

	}

}
